namespace Sage.Http.Options
{
    /// <summary>
    /// 日志记录选项配置
    /// </summary>
    public class LoggingOptions
    {
        /// <summary>
        /// 是否记录请求信息，默认为 true
        /// </summary>
        public bool LogRequests { get; set; } = true;

        /// <summary>
        /// 是否记录响应信息，默认为 true
        /// </summary>
        public bool LogResponses { get; set; } = true;

        /// <summary>
        /// 是否记录请求头信息，默认为 true
        /// </summary>
        public bool LogRequestHeaders { get; set; } = true;

        /// <summary>
        /// 是否记录响应头信息，默认为 true
        /// </summary>
        public bool LogResponseHeaders { get; set; } = true;

        /// <summary>
        /// 是否记录请求体内容，默认为 false
        /// </summary>
        public bool LogRequestBody { get; set; } = false;

        /// <summary>
        /// 是否记录响应体内容，默认为 false
        /// </summary>
        public bool LogResponseBody { get; set; } = false;

        /// <summary>
        /// 最大内容长度限制（字节），超过此长度的内容将被截断，默认为 4096
        /// </summary>
        public int MaxContentLength { get; set; } = 4096;

        /// <summary>
        /// 敏感头部名称列表，这些头部的值将被屏蔽
        /// </summary>
        public HashSet<string> SensitiveHeaders { get; set; } = new(StringComparer.OrdinalIgnoreCase)
        {
            "Authorization",
            "Cookie",
            "Set-Cookie",
            "X-API-Key",
            "X-Auth-Token",
            "Bearer",
            "Proxy-Authorization"
        };

        /// <summary>
        /// 是否记录请求和响应的时间信息，默认为 true
        /// </summary>
        public bool LogTiming { get; set; } = true;

        /// <summary>
        /// 是否记录请求的唯一标识符，默认为 true
        /// </summary>
        public bool LogRequestId { get; set; } = true;

        /// <summary>
        /// 二进制内容检测选项
        /// </summary>
        public BinaryContentDetectionOptions BinaryDetection { get; set; } = new();
        
        /// <summary>
        /// 创建当前选项的副本
        /// </summary>
        public LoggingOptions Clone()
        {
            return new LoggingOptions
            {
                LogRequests = this.LogRequests,
                LogResponses = this.LogResponses,
                LogRequestHeaders = this.LogRequestHeaders,
                LogResponseHeaders = this.LogResponseHeaders,
                LogRequestBody = this.LogRequestBody,
                LogResponseBody = this.LogResponseBody,
                MaxContentLength = this.MaxContentLength,
                SensitiveHeaders = new HashSet<string>(this.SensitiveHeaders, StringComparer.OrdinalIgnoreCase),
                LogTiming = this.LogTiming,
                LogRequestId = this.LogRequestId,
                BinaryDetection = this.BinaryDetection.Clone()
            };
        }
    }

    /// <summary>
    /// 二进制内容检测配置选项
    /// </summary>
    public class BinaryContentDetectionOptions
    {
        /// <summary>
        /// 是否启用字节级内容分析，默认为 true
        /// 当 MIME 类型不明确时，会读取内容的前几个字节进行分析
        /// </summary>
        public bool EnableContentAnalysis { get; set; } = true;

        /// <summary>
        /// 用于内容分析的字节数，默认为 512
        /// 只读取内容的前 N 个字节进行二进制检测，避免性能问题
        /// </summary>
        public int ContentAnalysisSampleSize { get; set; } = 512;

        /// <summary>
        /// 控制字符比例阈值，默认为 0.3
        /// 当内容中控制字符的比例超过此值时，认为是二进制内容
        /// </summary>
        public double ControlCharThreshold { get; set; } = 0.3;

        /// <summary>
        /// 高位字符比例阈值，默认为 0.95
        /// 当内容不是有效 UTF-8 且高位字符比例超过此值时，认为是二进制内容
        /// </summary>
        public double HighBitCharThreshold { get; set; } = 0.95;

        /// <summary>
        /// 自定义二进制 MIME 类型列表
        /// 可以添加项目特定的二进制类型
        /// </summary>
        public HashSet<string> CustomBinaryTypes { get; set; } = new(StringComparer.OrdinalIgnoreCase);

        /// <summary>
        /// 自定义文本 MIME 类型列表
        /// 可以添加项目特定的文本类型，这些类型会被强制当作文本处理
        /// </summary>
        public HashSet<string> CustomTextTypes { get; set; } = new(StringComparer.OrdinalIgnoreCase);
        
        /// <summary>
        /// 创建当前选项的副本
        /// </summary>
        public BinaryContentDetectionOptions Clone()
        {
            return new BinaryContentDetectionOptions
            {
                EnableContentAnalysis = this.EnableContentAnalysis,
                ContentAnalysisSampleSize = this.ContentAnalysisSampleSize,
                ControlCharThreshold = this.ControlCharThreshold,
                HighBitCharThreshold = this.HighBitCharThreshold,
                CustomBinaryTypes = new HashSet<string>(this.CustomBinaryTypes, StringComparer.OrdinalIgnoreCase),
                CustomTextTypes = new HashSet<string>(this.CustomTextTypes, StringComparer.OrdinalIgnoreCase)
            };
        }
    }
}